from google.appengine.api import taskqueue
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.api import users
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import channel

CHANNEL_KEY = str(1)

class Counter(db.Model):
    count = db.IntegerProperty(indexed=False)

class CounterHandler(webapp.RequestHandler):
    def get(self):
        key = CHANNEL_KEY

        counterTxn = CounterTransaction(key)
        counterTxn.init()

        token = channel.create_channel(key)
        template_values = {
                    'token': token,
                }

        self.response.out.write(template.render('index.html', template_values))

        # Add the task to the default queue.
        taskqueue.add(url='/worker')

class CounterTransaction:
    counter = None 
    key = None

    def __init__(self, _key):
        self.key = _key

    def inc(self):
        self.counter = Counter.get_by_key_name(self.key)
        if self.counter is None:
            self.counter = Counter(key_name=self.key, count=0)
        else:
            self.counter.count += 1
        self.counter.put()

    def reset(self):
        self.counter = Counter.get_by_key_name(self.key)
        if self.counter is None:
            self.counter = Counter(key_name=self.key, count=0)
        else:
            self.counter.count = 0
        self.counter.put()

    def init(self):
        db.run_in_transaction(self.reset)

    def run(self):
        db.run_in_transaction(self.inc)

class CounterWorker(webapp.RequestHandler):
    def post(self): # should run at most 1/s
        key = CHANNEL_KEY

        counterTxn = CounterTransaction(key)
        counterTxn.run()
        
        count = counterTxn.counter.count

        channel.send_message(CHANNEL_KEY, str(count))

        # Add the task to the default queue.
        taskqueue.add(url='/worker')


def main():
    run_wsgi_app(webapp.WSGIApplication([
        ('/', CounterHandler),
        ('/worker', CounterWorker),
    ]))

if __name__ == '__main__':
    main()
